﻿using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using SDT.Site.Models;
using SDT.Model;
using System.Text;
using System.Security.Cryptography;
using SDT.Lib.Common;
using SDT.Lib.Mail;
using SDT.Lib.MvcMembership;
using System.Configuration;
using SDT.Site.Properties;
using System.IO;
using SDT.Site.ViewModels;

namespace MAG.Site.Controllers
{

    [HandleError]
    public class AccountController : Controller
    {

        public IFormsAuthenticationService FormsService { get; set; }
        public IMembershipService MembershipService { get; set; }
       // private readonly IPasswordService _passwordService;
        protected override void Initialize(RequestContext requestContext)
        {
            if (FormsService == null) { FormsService = new FormsAuthenticationService(); }
            if (MembershipService == null) { MembershipService = new AccountMembershipService(); }
            //_passwordService = new AspNetMembershipProviderWrapper(Membership.Provider);
            base.Initialize(requestContext);
        }

        // **************************************
        // URL: /Account/LogOn
        // **************************************

        public ActionResult LogOn()
        {
            if (Request.IsAuthenticated)
            {
                SDTDataContext db = new SDTDataContext();
                var c = db.Customers.Where(e => e.UserName == HttpContext.User.Identity.Name || e.Email == HttpContext.User.Identity.Name).SingleOrDefault();
                if (c != null)
                {
                    return RedirectToAction("Index", "Order", new { area = "User" });
                }
                return View();
            }
            return View();
        }
        [HttpPost]
        public ActionResult Signin()
        {
            var dealYN = Request["hdDeal"] != null && Utils.ParseInt(Request["hdDeal"]) == 1 ? true : false;
            if (ModelState.IsValid)
            {
                
                var email = Request["emaillogin"];
                var pass = Request["passlogin"];
                var savePass = Request["checkcookie"] == "1" ? true : false;
                SDTDataContext db = new SDTDataContext();
                var c = db.Customers.Where(e => e.UserName == email || e.Email == email).SingleOrDefault();
                if (c != null)
                {
                    FormsService.SignIn(email, savePass); 
                }
                if (dealYN == false)
                {
                    return RedirectToAction("cart", "shopping", new { area = "" });
                }
                else {
                    return RedirectToAction("cart", "deal", new { area = "" }); 
                }
            }
            if (dealYN == false)
            {
                return RedirectToAction("cart", "shopping", new { area = "" });
            }
            else
            {
                return RedirectToAction("cart", "deal", new { area = "" });
            }
        }
        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {

            if (ModelState.IsValid)
            {
                SDTDataContext db = new SDTDataContext();
                var c = db.Customers.Where(e => (e.UserName == model.UserName || e.Email == model.UserName) && 
                    e.Password == Utils.EnCryptPassword(model.Password)).SingleOrDefault();
                if (c != null)
                {
                    FormsService.SignIn(model.UserName, model.RememberMe);
                    if (!String.IsNullOrEmpty(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("index", "order", new { area = "user" });
                    }
                }
                else
                {
                    ModelState.AddModelError("", "Tên đăng nhập hoặc mật khẩu không chính xác!.");
                }
            }
            // If we got this far, something failed, redisplay form
            return View(model);
        }

        // **************************************
        // URL: /Account/LogOff
        // **************************************

        public ActionResult LogOff()
        {
            FormsService.SignOut();
            Session[SDT.Lib.Common.Messages.Cart] = null;
            return RedirectToAction("Index", "Home");
        }

        // **************************************
        // URL: /Account/Register
        // **************************************

        public ActionResult Register()
        {
            try
            {
                SDTDataContext db = new SDTDataContext();
                CustomerEditModels c = new CustomerEditModels();
                c.Cities = db.Cities.ToList();
                c.Districts = db.Districts.ToList();
                c.Sexuals = Utils.StringToDictionaryIntString(Settings.Default.CustomerSexual, ",");
                return View(c);
            }
            catch (Exception exp)
            {
                ViewData[Messages.MessageInfo] = exp.Message;
                return View();
            }
        }

        [HttpPost]
        public ActionResult Register(CustomerEditModels c)
        {
            try
            {
                SDTDataContext db = new SDTDataContext();
                if (Request["CaptchaText"].ToLower() == HttpContext.Session["captchastring"].ToString().ToLower())
                {
                    // Attempt to register the user                
                    UpdateModel(c);
                    var confirmPass = Request["txtConfirmPassword"];
                    if (c.Customer.Password != confirmPass)
                    {
                        ViewData[Messages.MessageInfo] = Messages.ERR_CUS_001;
                        return View();
                    }
                    c.Customer.UserName = c.Customer.Email;
                    c.Customer.CityID = Utils.ParseInt(Request["ddlCity"]);
                    c.Customer.DistrictID = Utils.ParseInt(Request["ddlDistrict"]);
                    c.Customer.SexID = Utils.ParseInt(Request["rdoSex"]);
                    c.Customer.Password = Utils.EnCryptPassword(c.Customer.Password);
                    c.Customer.AddDate = DateTime.Now;
                    c.Customer.IsLockedOut = false;
                    c.Customer.LastLoginDate = DateTime.Now;
                    c.Customer.LastPasswordChangedDate = DateTime.Now;
                    c.Customer.LoweredEmail = c.Customer.Email.ToLower();
                    c.Customer.LoweredUserName = c.Customer.UserName.ToLower();
                    c.Customer.ActiveLink = Guid.NewGuid().ToString();
                    db.Customers.InsertOnSubmit(c.Customer);
                    db.SubmitChanges();
                    FormsService.SignIn(c.Customer.UserName, true);
                    return View("RegisterSuccess");
                }
                else
                {
                    ViewData[Messages.MessageInfo] = Messages.ERR_CAPTCHA_VALIDATE;
                    return View();
                }
            }
            catch (Exception exp)
            {
                ViewData[Messages.MessageInfo] = exp.Message;
                return View("RegisterFail");
            }
            
        }
        [HttpPost]
        public ActionResult Create()
        {
            try
            {
                var dealYN = Request["hdDeal"] != null && Utils.ParseInt(Request["hdDeal"]) == 1 ? true : false;
                if (ModelState.IsValid)
                {
                    SDTDataContext db = new SDTDataContext();                    
                    var name = Request["Customer.FullName"];
                    var phone = Request["Customer.MobilePhone"];
                    var cityid =Utils.ParseInt(Request["ddlCity"]);
                    var districtid =Utils.ParseInt(Request["ddlDistrict"]);
                    var adrress = Request["Customer.Address"];
                    var email = Request["Customer.Email"];
                    var pass = Request["Customer.Password"];
                    var birthday = Utils.ParseDateTime(Request["txtBirthday"], new System.Globalization.CultureInfo("vi-VN"));
                    var sexid = Utils.ParseInt(Request["rdoSex"]);
                    var c = new Customer();
                    c.FullName = name;
                    c.MobilePhone = phone;
                    c.CityID = cityid;
                    c.DistrictID = districtid;
                    c.Address = adrress;
                    c.Password = Utils.EnCryptPassword(pass);
                    c.UserName = email;
                    c.Email = email;
                    c.AddDate = DateTime.Now;
                    c.IsLockedOut = false;
                    c.LoweredEmail = email.ToLower();
                    c.LoweredUserName = email.ToLower();
                    c.SexID = sexid;
                    var exist = db.Customers.Where(e => e.Email == email).FirstOrDefault();
                    if (exist == null)
                    {
                        db.Customers.InsertOnSubmit(c);
                        db.SubmitChanges();
                        FormsService.SignIn(c.UserName, true);
                    }
                    else
                    {
                        throw new Exception("Tài khoản đã tồn tại. Bạn không thể tạo mới tài khoản này.");
                    }
                }
                if (dealYN == false)
                    return RedirectToAction("cart", "shopping", new { area = "" });
                else {
                    return RedirectToAction("cart", "deal", new { area = "" });
                }
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }
        public ActionResult Active()
        {
            try
            {
                var k = Request["k"];
                if (k != null && k != string.Empty)
                {
                    SDTDataContext db = new SDTDataContext();
                    var u = db.aspnet_Memberships.Where(e => e.UserId.ToString() == k).FirstOrDefault();
                    if (u != null)
                    {
                        u.IsApproved = true;
                        db.SubmitChanges();
                        FormsService.SignIn(u.aspnet_User.UserName, false /* createPersistentCookie */);
                        return RedirectToAction("Index", "User/Product");
                    }

                }
                return RedirectToAction("Index", "Home");
            }
            catch(Exception exp) {
                return RedirectToAction("Index", "Home");
            }
        }
        
        // **************************************
        // URL: /Account/ChangePassword
        // **************************************

        [Authorize]
        public ActionResult ChangePassword()
        {
            ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
            return View();
        }
        public ActionResult ResetPassword()
        {
            ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
            return View();
        }
        [HttpPost]
        public ActionResult ResetPassword(RegisterModel model)
        {
            string ResetPasswordBody = "Mật khẩu mới là: ";
            string ResetPasswordSubject = "[Muaqua.vn] Mật khẩu mới";
            var user =CustomerManager.GetUser(Request["txtEmail"]);
            if (user == null) return RedirectToAction("index", "home");
            var newPassword = Utils.GetRandomPassword(8);
            string fromMail = ConfigurationManager.AppSettings["DefaultFromMail"];
            var body = ResetPasswordBody + newPassword;
            try
            {
                SmtpMailer.sendMail(user.Email, fromMail, ResetPasswordSubject, body);
                SDTDataContext db = new SDTDataContext();
                var c = db.Customers.Where(e => e.Email == Request["txtEmail"]).SingleOrDefault();
                if (c != null) c.Password = Utils.EnCryptPassword(newPassword);
                db.SubmitChanges();
            }
            catch (Exception exp)
            {
                ViewData[Messages.MessageInfo] = exp.Message;
                return View("ResetFail");
            }
            return View("ResetSuccess");
        }
        [Authorize]
        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {
                SDTDataContext db = new SDTDataContext();
                var c = db.Customers.Where(e => (e.UserName == User.Identity.Name || e.Email == User.Identity.Name) 
                    && e.Password == Utils.EnCryptPassword(model.OldPassword)).SingleOrDefault();

                if (c != null)
                {
                    if (model.NewPassword == model.ConfirmPassword)
                    {
                        c.Password = Utils.EnCryptPassword(model.NewPassword);
                        db.SubmitChanges();
                        return RedirectToAction("ChangePasswordSuccess");
                    }
                    else
                    {
                        ModelState.AddModelError("", "Mật khẩu thay đổi không đúng.");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "Mật khẩu thay đổi không đúng");
                }
            }

            // If we got this far, something failed, redisplay form
            ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
            return View(model);
        }

        // **************************************
        // URL: /Account/ChangePasswordSuccess
        // **************************************

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }
        //encrypt
        protected string EncryptPassword(string password)
        {
            // Produses an MD5 hash string of the password
            //we use codepage 1252 because that is what sql server uses
            byte[] pwdBytes = Encoding.GetEncoding(1252).GetBytes(password);
            byte[] hashBytes = System.Security.Cryptography.MD5.Create().ComputeHash(pwdBytes);
            return Encoding.GetEncoding(1252).GetString(hashBytes);
        }

        //2
        public string GenerateSalt()
        {
            byte[] buf = new byte[16];
            (new RNGCryptoServiceProvider()).GetBytes(buf);
            return Convert.ToBase64String(buf);
        }
        public string EncodePassword(string pass, int passwordFormat, string salt)
        {
            if (passwordFormat == 0) // MembershipPasswordFormat.Clear
                return pass;

            byte[] bIn = Encoding.Unicode.GetBytes(pass);
            byte[] bSalt = Convert.FromBase64String(salt);
            byte[] bAll = new byte[bSalt.Length + bIn.Length];
            byte[] bRet = null;

            Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
            Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length);
            if (passwordFormat == 1)
            { // MembershipPasswordFormat.Hashed
                HashAlgorithm s = HashAlgorithm.Create("SHA1");
                // Hardcoded "SHA1" instead of Membership.HashAlgorithmType
                bRet = s.ComputeHash(bAll);
            }
            return Convert.ToBase64String(bRet);
        }

    }
}
